/**
 * webpack.config.js webpack的配置文件
 * 作用：指示webpack干那些活（当运行webpack指令时，会加载里面的配置）
 * commonjs
 * loader: 1.下载 2.使用
 * plugins 1.下载 2.引入 3.使用
 */

const os = require('os')
// resolve用来拼接绝对路径的方法
const { resolve } = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const ESLintPlugin = require('eslint-webpack-plugin')
const MiniCssExtractPlugin = require("mini-css-extract-plugin")
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin")
const TerserWebpackPlugin = require('terser-webpack-plugin')
const WorkboxPlugin = require('workbox-webpack-plugin')

const threads = os.cpus().length // cpu核数

module.exports = {
	// webpack 配置
	// 入口起点
	entry: './src/index.js',
	// 输出
	output: {
		// 输出文件名
		filename: 'static/js/[name].js',
		// 输出路径
		// __dirname nodejs的变量，代表当前文件的目录的绝对路径
		path: resolve(__dirname, '../dist'),
		// 自动清空上次打包结果
		clean: true,
		// 给打包输出的其他文件命名
		chunkFilename: "static/js/[name].chunk.js",
		// 图片 字体等通过type:asset 处理命名资源方式
		assetModuleFilename: "static/media/[hash:10][ext][query]"
	},
	// loader的配置
	module: {
		rules: [
			// 详细的loader配置
			// 不同文件必须配置不同的loader
			{
				oneOf: [
					{
						// 匹配那些文件,正则表达式
						test: /\.css$/,
						// 使用那些loader进行处理
						use: [ // use数组loader执行循序：从下往上依次执行
							// 将创建style标签，将js中的样式资源插入，添加到head中生效
							MiniCssExtractPlugin.loader,
							// 将css文件变成 commonjs 模块加载到js中，里面的内容是样式字符串
							'css-loader',
							{
								loader: 'postcss-loader',
								options: {
								  postcssOptions: {
									plugins: [
									  [
										'postcss-preset-env', // 能解决大多数样式兼容问题
										// {
										//   // 其他选项
										// },
									  ],
									],
								  },
								}
							}
						]
					},
					{
						test: /.less$/,
						use: [ // use数组loader执行循序：从下往上依次执行
							// 将创建style标签，将js中的样式资源插入，添加到head中生效
							MiniCssExtractPlugin.loader,
							// 将css文件变成 commonjs 模块加载到js中，里面的内容是样式字符串
							'css-loader',
							'less-loader'
						]
					},
					{
						test: /.s[ac]ss$/,
						use: [ // use数组loader执行循序：从下往上依次执行
							// 将创建style标签，将js中的样式资源插入，添加到head中生效
							MiniCssExtractPlugin.loader,
							// 将css文件变成 commonjs 模块加载到js中，里面的内容是样式字符串
							'css-loader',
							'sass-loader'
						]
					},
					{
						test: /\.(png|jpe?g|gif|webp|svg)$/,
						type: 'asset',
					    parser: {
							dataUrlCondition: {
								maxSize: 10 * 1024 // 小于10kb转base64
							}
					    },
					 //    generator: {
						// 	// 输出图片名字
						// 	filename: 'static/images/[hash:10][ext][query]'
						// }
					},
					{ // 字体图标 以及其他资源
						test: /\.(ttf|woff2?|mp3|mp4|avi)$/,
						type: 'asset/resource',
					 //    generator: {
						// 	// 输出图片名字
						// 	filename: 'static/media/[hash:10][ext][query]'
						// }
					},
					{
						test: /\.m?js$/,
						exclude: /(node_modules|bower_components)/, // 排除node_modules中的文件
						// include: resolve(__dirname, "../src"), // 只处理src下的文件，其他文件不处理
						use: [
							{
								loader: 'thread-loader',
								options: {
									works: threads // 进程数量
								}
							},
							{
								loader: 'babel-loader',
								options: {
									// presets: ['@babel/preset-env'],
									cacheDirectory: true, // 开启babel缓存
									cacheCompression: false, // 关闭缓存文件压缩
									// plugin: ["@babel/plugin-transform-runtime"], // 减少代码体积（ps：这个有问题）
								}
							}
						]
					}
				]
			}
		]
	},
	plugins: [
		// 详细的plugins配置
		// html-webpack-plugin
		// 默认会创建一个空HTML，自动引入打包输出的所有资源（JS/CSS）
		new HtmlWebpackPlugin({
			// 复制./src/index.html文件，并自动引入打包输出的所有资源（JS/CSS）
			template: './src/index.html'
		}),
		// eslint配置
		new ESLintPlugin({
			// 检测哪些文件
			context: resolve(__dirname, "../src"),
			exclude: "node_modules", // 排除node_modules中的文件
			// include: resolve(__dirname, "../src"), // 只处理src下的文件，其他文件不处理
			cache: true, // 开启缓存
			cacheLocation: resolve(__dirname, "../node_modules/.cache/eslintCache"),
			threads, // 开启多进程
		}),
		new MiniCssExtractPlugin({
			filename: 'static/css/[name].css',
			chunkFilename: 'static/css/[name].chunk.css'
		}),
		// 压缩css
		// new CssMinimizerPlugin(),
		// new TerserWebpackPlugin({
		// 	parallel: threads // 开启多进程和进程数量
		// })
		new WorkboxPlugin.GenerateSW({
			// 这些选项帮助快速启用 ServiceWorkers
			// 不允许遗留任何“旧的” ServiceWorkers
			clientsClaim: true,
			skipWaiting: true,
		}),
	],
	optimization: {
		// webpack5 压缩操作 放置在这里
		minimizer: [
			// 压缩css
			new CssMinimizerPlugin(),
			// 自动开启的 只是因为要写配置所有手动写一遍
			new TerserWebpackPlugin({
				parallel: threads
			})
		],
		
		// 代码分割配置
		splitChunks: {
			chunks: 'all', // 对所以模块进行分割
		},
		runtimeChunk: {
			name: (entrypoint) => `runtime~${entrypoint.name}.js`
		}
	},
	// 模式
	// mode: 'development', // 开发模式
	mode: 'production', // 生产模式
	// devServer: {
	// 	host: 'localhost', // 域名
	// 	port: 3000, // 端口
	// 	open: true, // 是否自动打开浏览器
	// }
	devtool: "source-map",
}


// package.json 的 browserslist
//// 浏览器兼容性做到什么程度 // 所有浏览器最近两个版本 // 覆盖99%浏览器  // 不用已经死了的浏览器

// three shakin@g 用于移除js中没有使用上的代码 webpack默认开启，无需其他配置